{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Linear Regression From Scratch.\n",
    "\n",
    "    Divyanshu Vyas | dvyas13ad@gmail.com\n",
    "    \n",
    "    This Notebook will help us understand how we can perform Linear Regresssion with Just basic Python Knowledge."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [],
   "source": [
    "x1 = np.random.random(10000)\n",
    "x2 = np.random.random(10000)\n",
    "x3 = np.random.random(10000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = x1 +5*x2 - 10*x3 + 20\n",
    "\n",
    "w_actual = [1 , 5, -10]\n",
    "b_actual = 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({'x1':x1 , 'x2':x2 , 'x3' :x3 , 'y':y})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.array(df[['x1' , 'x2' , 'x3']])\n",
    "\n",
    "y = np.array(df['y']).reshape(10000,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cost(w,b,X,y):\n",
    "    \n",
    "    #X - 10000x3\n",
    "    #y - 10000x1\n",
    "    #w - 3x1\n",
    "    #b = 1x1\n",
    "    \n",
    "    Z = np.dot(X , w) + b\n",
    "    \n",
    "    L = (y - Z)**2\n",
    "    \n",
    "    m = len(y)\n",
    "    \n",
    "    J = np.sqrt((1/m)*np.sum(L))\n",
    "    \n",
    "    return J\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Some Formulas\n",
    "\n",
    "## 1. $ J(w,b) = \\frac {1}{m} \\sum [y - (W.X + b)]^2 $\n",
    "\n",
    "## 2. $ \\frac {\\partial J}{\\partial W} = \\frac {-2}{m} (X^T . [y - (W.X + b)]) $\n",
    "\n",
    "## 3. $ \\frac {\\partial J} {\\partial b} = \\frac {-2}{m} \\sum [ y - (W.X + b) ] $"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gradient(w,b,X,y):\n",
    "    \n",
    "    #dw = dJ/dw = 3x1\n",
    "    #db = dJ/db = 1x1\n",
    "    \n",
    "        \n",
    "    #X - 10000x3\n",
    "    #y - 10000x1\n",
    "    #w - 3x1\n",
    "    #b = 1x1\n",
    "    \n",
    "    Z = np.dot(X , w) + b\n",
    "    \n",
    "    J = cost(w,b,X,y)\n",
    "    \n",
    "    m = X.shape[0]\n",
    "    \n",
    "    dw = (-2/m)*np.dot(X.T , (y - Z))\n",
    "    \n",
    "    db = (-2/m)*np.sum(y - Z)\n",
    "    \n",
    "    return dw , db\n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "# X.shape\n",
    "\n",
    "# y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "17.48268154108733"
      ]
     },
     "execution_count": 113,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Just a check on how terrible our initial guess is performing.\n",
    "w = np.random.random((3,1))\n",
    "b = 0\n",
    "\n",
    "cost(w,b,X,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Now Let's Make it Learn!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [],
   "source": [
    "def learning(w,b,X,y,epoch):\n",
    "    \n",
    "    #dw = dJ/dw = 3x1\n",
    "    #db = dJ/db = 1x1\n",
    "    \n",
    "    #X - 10000x3\n",
    "    #y - 10000x1\n",
    "    #w - 3x1\n",
    "    #b = 1x1\n",
    "    \n",
    "    Z = np.dot(X , w) + b\n",
    "    \n",
    "    costs = []\n",
    "    \n",
    "    costs.append(cost(w,b,X,y))\n",
    "    \n",
    "    for e in range(epoch):\n",
    "        \n",
    "        dw , db = gradient(w,b,X,y)\n",
    "        \n",
    "        w = w - 0.005*dw\n",
    "        \n",
    "        b = b - 0.005*db\n",
    "        \n",
    "        if e%100 == 0:\n",
    "            costs.append(cost(w,b,X,y))\n",
    "        \n",
    "    \n",
    "    wf = w\n",
    "    bf = b\n",
    "    \n",
    "    return wf , bf , costs\n",
    "    \n",
    "    \n",
    "    \n",
    "        \n",
    "        \n",
    "    \n",
    "    \n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "wf , bf , costs = learning(w,b,X,y,10000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[ 1.0657494 ],\n",
       "        [ 5.06359242],\n",
       "        [-9.92998038]]),\n",
       " 19.895068110806836)"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wf , bf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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iCl0UdaWLVsghMDIkSNNHiMjIwPXrl3TL9+5cwcvv/wymjdvjt69e+PKlSs4ePAgOnToUL5vxlpxceZDbEwM0KVLwXJurvmbVBARERFRsRxa4Q0LC0NJk0S8/PLLePnll81uT0pKMlhesmQJlixZUhbNcxx5uIOPD5CVBbzyirQMsNJLREREZCVFjOF9rBS+QO2zz6TAO3o0EBjI0EtERERkAwZeZ1N4bO/WrdK6R48KQq5O57i2ERERESkQA6+ziYsr+Fmec1i+KQYru0RERERWU8Q8vI8t+WYYjx45th1ERERECsbA68yKVniJiIiIyGoMvM6MFV4iIiKiUmPgdWas8BIRERGVGgOvM2OFl4iIiKjUGHidGSu8RERERKXGwOvMWOElIiIiKjUGXmfGCi8RERFRqTHwOjNWeImIiIhKjYHXmbHCS0RERFRqDLzOjBVeIiIiolJj4HVmrPASERERlRoDrzNjhZeIiIio1Bh4nRkrvERERESlxsDrzFjhJSIiIio1Bl5nxgovERERUakx8DozVniJiIiISo2B15mxwktERERUagy8zowVXiIiIqJSY+B1ZnLgZYWXiIiIyGYMvM5MHtLACi8RERGRzRh4nRkrvERERESlxsDrzFjhJSIiIio1Bl5nVrjCK4Rj20JERESkUAy8zkyu8ObnA3l5jm0LERERkUIx8DozucILcBwvERERkY0cGngPHjyI/v37IzAwECqVCjt37jTYPm7cOKhUKoNHp06dSjzutm3bEBISAo1Gg5CQEOzYsaO83kL5Khx4OY6XiIiIyCYODbwPHjxAq1atsHz5crP7PP3007h27Zr+sXv37mKPmZKSgueeew6jR4/GqVOnMHr0aAwfPhxHjhwp6+aXP1dXwM1N+pkVXiIiIiKbuDny5JGRkYiMjCx2H41GA39/f4uPmZCQgIiICERFRQEAoqKikJycjISEBGzevLlU7XUIDw/g/n1WeImIiIhs5NDAa4mkpCTUrFkTVapUQY8ePTB//nzUrFnT7P4pKSl48803Ddb16dMHCQkJZl+Tk5ODnEIV1KysLACAVquFVqst5TsomXwOU+dy02igun8f2vv3ATu0hWxTXB+SMrAPlY99qGzsP+Wzdx9acx6nDryRkZEYNmwYgoODkZaWhujoaPTs2RPHjx+HpvD41kIyMzNRq1Ytg3W1atVC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Ci8RERGRFawe0uDm5obg4GDodLryaA8VhzM1EBEREVnNpjG8s2fPRlRUFG7dulXW7aHicC5eIiIiIqvZNIZ36dKluHDhAgIDAxEcHAwvLy+D7SdOnCiTxlERrPASERERWc2mwDto0KCybgdZghVeIiIiIqvZdNEaAIwfPx5BQUFl3iAqBiu8RERERFaz6aK1xYsX86I1R2CFl4iIiMhqNl201qtXLyQlJZVxU6hErPASERERWc2mMbyRkZGIiorCr7/+irZt2xpdtDZgwIAyaRwVwQovERERkdVsCryvvvoqAOD999832qZSqTjcobywwktERERkNZsCb35+flm3gyzBCi8RERGR1awaw9u3b1/cvXtXvzx//nzcuXNHv3zz5k2EhISUXevIECu8RERERFazKvB+9913yCkUthYuXGhwt7W8vDykpqaWXevIECu8RERERFazKvAKIYpdpnLGCi8RERGR1WyalowchBVeIiIiIqtZFXhVKhVUKpXROrITVniJiIiIrGbVLA1CCIwbNw6av4LXo0eP8Morr+jn4c0phyBWr149XLx40Wj9xIkTsWLFCqP1SUlJCA8PN1p/7tw5NGvWrMzbZ1es8BIRERFZzarAO3bsWIPlF154wWifMWPGlK5FRRw9etRgXt9ff/0VERERGDZsWLGvS01NhY+Pj365Ro0aZdouh2CFl4iIiMhqVgXetWvXllc7zCoaVN999100bNgQPXr0KPZ1NWvWRJUqVcqzafbHCi8RERGR1Wy68YSj5ObmYsOGDZg6dWqJY4dDQ0Px6NEjhISEYPbs2SaHOchycnIMhmNkZWUBALRaLbRabdk0vhjyOUo6l4ubG1wB5D98CJ0d2kWWs7QPyXmxD5WPfahs7D/ls3cfWnMelVDQ3GKff/45Ro0ahYyMDAQGBprcJzU1FQcPHkTbtm2Rk5OD9evXY/Xq1UhKSkL37t1NviYuLg7x8fFG6zdt2gRPT88yfQ+lUff77xG6bBky27bFkehoRzeHiIiIyGGys7MxatQo3L1712AYqymKCrx9+vSBu7s7vvnmG6te179/f6hUKnz99dcmt5uq8AYFBeHGjRslfoBlQavVIjExEREREVCr1Wb3U23eDLexY5Hfsyd0e/aUe7vIcpb2ITkv9qHysQ+Vjf2nfPbuw6ysLFSvXt2iwKuYIQ0XL17Evn37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\n",
      "text/plain": [
       "<Figure size 800x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize = (8,4))\n",
    "plt.style.use('default')\n",
    "plt.plot(costs ,c='red' , marker='x')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Error')\n",
    "plt.title('Optimization Progress : Linear Regression!')\n",
    "\n",
    "plt.grid()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [],
   "source": [
    "Actual = ['w1 = 1' , 'w2 =5' , 'w3 = -10', 'b = 20']\n",
    "\n",
    "ModelResults = [f'w1 = {wf[0][0]}' ,f'w2 = {wf[1][0]}',f'w3 = {wf[2][0]}', f'b = {bf}' ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [],
   "source": [
    "results = pd.DataFrame({'Actual Parameters':Actual , 'Model-Parameters':ModelResults})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Actual Parameters</th>\n",
       "      <th>Model-Parameters</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>w1 = 1</td>\n",
       "      <td>w1 = 1.0657494018932743</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>w2 =5</td>\n",
       "      <td>w2 = 5.063592418656829</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>w3 = -10</td>\n",
       "      <td>w3 = -9.92998037745159</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>b = 20</td>\n",
       "      <td>b = 19.895068110806836</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Actual Parameters         Model-Parameters\n",
       "0            w1 = 1  w1 = 1.0657494018932743\n",
       "1             w2 =5   w2 = 5.063592418656829\n",
       "2          w3 = -10   w3 = -9.92998037745159\n",
       "3            b = 20   b = 19.895068110806836"
      ]
     },
     "execution_count": 129,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
